/*
ont-space - The ontology-based resource metadata repository
Copyright (c) 2006-2008, Information Eng. Research Unit - Univ. of Alcalá
http://www.cc.uah.es/ie
This library is free software; you can redistribute it and/or modify it under
the terms of the GNU Lesser General Public License as published by the Free
Software Foundation; either version 2.1 of the License, or (at your option)
any later version.
This library is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
details.
You should have received a copy of the GNU Lesser General Public License along
with this library; if not, write to the Free Software Foundation, Inc.,
59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
 */
package org.ontspace.util.translator.lom2owl.owl;

import org.ieee.ltsc.lom.LOM;
import org.ieee.ltsc.lom.LOMUtil;

import java.io.*;
import com.hp.hpl.jena.ontology.*;
import com.hp.hpl.jena.rdf.model.RDFNode;

/**
 * Translates a LOM langstring item to its representation in OWL.  
 *
 */
public class LS2LSTranslator extends ElementTranslatorImpl {

    private String category =
            new String();
    private String attributeName =
            new String();
    private String element =
            new String();

    /** Creates a new instance of LS2LSTranslator */
    public LS2LSTranslator(String elementCategory, String elementElement,
            String elementAttribute) {

        this.category =
                elementCategory;
        this.attributeName =
                elementAttribute;
        this.element =
                elementElement;
    }

    /**
     * This method translates a LOM langstring item to its representation 
     * in OWL
     * @param lom The metadata record
     * @param ont The ontology
     * @param inst The instance of learning Object
     * @param nsName The namespace
     * @param errorWriter The error file
     */
    public void apply(LOM lom, OntModel ont, Individual inst, String nsName,
            PrintWriter errorWriter) {


        //  1) Get the information from lom xml file
        OntClass langStringClass =
                ont.getOntClass(nsName + "#langString");
        OntClass singleLangStringClass =
                ont.getOntClass(nsName +
                "#singleLangString");
        ObjectProperty includeLangStringProperty =
                ont.getObjectProperty(nsName + "#includesSingleLangString");
        DatatypeProperty hasValueProperty =
                ont.getDatatypeProperty(nsName +
                "#hasValue");
        DatatypeProperty inLanguageProperty =
                ont.getDatatypeProperty(nsName +
                "#inLanguage");

        String instance =
                null;
        if (category.equals("General")) {
            //1.2 title 
            if (element.equals("Title")) {

                if (LOMUtil.getGeneralTitle(lom) != null) {
                    int i =
                            0;
                    instance =
                            "#lsGT" + inst.getLocalName().substring(3) + "-" +
                            String.valueOf(i);
                    Individual langInstance =
                            ont.createIndividual(nsName +
                            instance, langStringClass);
                    while ((LOMUtil.getString(LOMUtil.getGeneralTitle(lom), i)) !=
                            null) {
                        String titleLOM =
                                LOMUtil.getString(LOMUtil.getGeneralTitle(lom),
                                i);
                        String languageLOM =
                                LOMUtil.getLanguage(LOMUtil.getGeneralTitle(lom),
                                i);

                        instance =
                                "#slsGT" +
                                inst.getLocalName().substring(3) + "-" +
                                String.valueOf(i);
                        Individual singleInstance =
                                ont.createIndividual(nsName + instance,
                                singleLangStringClass);
                        if (titleLOM != null) {
                            RDFNode titleValue =
                                    ont.createTypedLiteral(titleLOM);
                            singleInstance.setPropertyValue(hasValueProperty,
                                    titleValue);
                        } else {
                            String log =
                                    "The Title field of the General category must contain a value";
                            errorWriter.println(log);
                        }
                        if (languageLOM != null) {
                            RDFNode languageValue =
                                    ont.createTypedLiteral(languageLOM);
                            singleInstance.setPropertyValue(inLanguageProperty,
                                    languageValue);
                        } else {
                            String log =
                                    "The Language field of Title in the General category must contain a value";
                            errorWriter.println(log);
                        }
                        langInstance.addProperty(includeLangStringProperty,
                                singleInstance);

                        i++;
                    }
                    ObjectProperty titleProperty =
                            ont.getObjectProperty(nsName + "#hasTitle");
                    inst.setPropertyValue(titleProperty, langInstance);
                }
            } //1.4 description
            else if (element.equals("Description")) {
                int i =
                        0;
                int j =
                        0;

                ObjectProperty descriptionProperty =
                        ont.getObjectProperty(nsName + "#hasDescription");
                while (LOMUtil.getGeneralDescription(lom, i) != null) {
                    instance =
                            "#lsGD" +
                            inst.getLocalName().substring(3) + "-" +
                            String.valueOf(i);
                    Individual langInstance =
                            ont.createIndividual(nsName +
                            instance, langStringClass);
                    j =
                            0;
                    while ((LOMUtil.getString(LOMUtil.getGeneralDescription(lom,
                            i), j)) != null) {
                        String descriptionLOM =
                                LOMUtil.getString(LOMUtil.getGeneralDescription(lom,
                                i), j);
                        String languageLOM =
                                LOMUtil.getLanguage(LOMUtil.getGeneralDescription(lom,
                                i), j);

                        instance =
                                "#slsGD" +
                                inst.getLocalName().substring(3) + "-" +
                                String.valueOf(j);
                        Individual singleInstance =
                                ont.createIndividual(nsName + instance,
                                singleLangStringClass);

                        if (descriptionLOM != null) {
                            RDFNode descriptionValue =
                                    ont.createTypedLiteral(descriptionLOM);
                            singleInstance.setPropertyValue(hasValueProperty,
                                    descriptionValue);
                        } else {
                            String log =
                                    "The Description field of the General category must contain a value";
                            errorWriter.println(log);
                        }
                        if (languageLOM != null) {
                            RDFNode languageValue =
                                    ont.createTypedLiteral(languageLOM);
                            singleInstance.setPropertyValue(inLanguageProperty,
                                    languageValue);
                        } else {
                            String log =
                                    "The Language field of Description in the General category must contain a value";
                            errorWriter.println(log);
                        }
                        langInstance.addProperty(includeLangStringProperty,
                                singleInstance);

                        inst.addProperty(descriptionProperty, langInstance);
                        j++;
                    }
                    i++;
                }
            } //1.5 keyword
            else if (element.equals("Keyword")) {

                int i =
                        0;
                int j =
                        0;
                ObjectProperty keywordProperty =
                        ont.getObjectProperty(nsName +
                        "#hasKeyword");
                while (LOMUtil.getGeneralKeyword(lom, i) != null) {
                    instance =
                            "#lsGK" +
                            inst.getLocalName() + "-" + String.valueOf(i);
                    Individual langInstance =
                            ont.createIndividual(nsName +
                            instance, langStringClass);
                    while ((LOMUtil.getString(LOMUtil.getGeneralKeyword(lom, i),
                            j)) != null) {
                        String keywordLOM =
                                LOMUtil.getString(LOMUtil.getGeneralKeyword(lom,
                                i), j);
                        String languageLOM =
                                LOMUtil.getLanguage(LOMUtil.getGeneralKeyword(lom,
                                i), j);

                        instance =
                                "#slsGK" +
                                inst.getLocalName() + "-" + String.valueOf(j);
                        Individual singleInstance =
                                ont.createIndividual(nsName + instance,
                                singleLangStringClass);
                        if (keywordLOM != null) {
                            RDFNode keywordValue =
                                    ont.createTypedLiteral(keywordLOM);
                            singleInstance.setPropertyValue(hasValueProperty,
                                    keywordValue);
                        } else {
                            String log =
                                    "The Kewyord field of the General category must contain a value";
                            errorWriter.println(log);
                        }
                        if (languageLOM != null) {
                            RDFNode languageValue =
                                    ont.createTypedLiteral(languageLOM);
                            singleInstance.setPropertyValue(inLanguageProperty,
                                    languageValue);
                        } else {
                            String log =
                                    "The Language field of Keyword in the General category must contain value";
                            errorWriter.println(log);
                        }
                        langInstance.addProperty(includeLangStringProperty,
                                singleInstance);
                        inst.addProperty(keywordProperty, langInstance);
                        j++;
                    }
                    i++;
                    j =
                            0;
                }


            } //1.6 coverage
            else if (element.equals("CoverageLO")) {
                int i =
                        0;
                int j =
                        0;

                ObjectProperty coverageProperty =
                        ont.getObjectProperty(nsName +
                        "#hasCoverage");
                while (LOMUtil.getGeneralCoverage(lom, i) != null) {
                    instance =
                            "#lsGC" +
                            inst.getLocalName() + "-" + String.valueOf(i);
                    Individual langInstance =
                            ont.createIndividual(nsName +
                            instance, langStringClass);
                    j =
                            0;
                    while ((LOMUtil.getString(LOMUtil.getGeneralCoverage(lom, i),
                            j)) != null) {
                        String coverageLOM =
                                LOMUtil.getString(LOMUtil.getGeneralCoverage(lom,
                                i), j);
                        String languageLOM =
                                LOMUtil.getLanguage(LOMUtil.getGeneralCoverage(lom,
                                i), j);
                        instance =
                                "#slsGC" +
                                inst.getLocalName() + "-" + String.valueOf(j);
                        Individual singleInstance =
                                ont.createIndividual(nsName + instance,
                                singleLangStringClass);
                        if (coverageLOM != null) {
                            RDFNode coverageValue =
                                    ont.createTypedLiteral(coverageLOM);
                            singleInstance.setPropertyValue(hasValueProperty,
                                    coverageValue);
                        } else {
                            String log =
                                    "The Coverage field of the General category must contain a value";
                            errorWriter.println(log);
                        }
                        if (languageLOM != null) {
                            RDFNode languageValue =
                                    ont.createTypedLiteral(languageLOM);
                            singleInstance.setPropertyValue(inLanguageProperty,
                                    languageValue);
                        } else {
                            String log =
                                    "The Language field of Coverage in the General category must contain a value";
                            errorWriter.println(log);
                        }
                        langInstance.addProperty(includeLangStringProperty,
                                singleInstance);

                        inst.addProperty(coverageProperty, langInstance);
                        j++;
                    }
                    i++;

                }

            }
        } else if (category.equals("LifeCycle")) {
            //2.1 version
            if (element.equals("Version")) {
                if (LOMUtil.getLifeCycleVersion(lom) != null) {
                    instance =
                            "#lsLV" +
                            inst.getLocalName();
                    Individual langInstance =
                            ont.createIndividual(nsName +
                            instance, langStringClass);
                    int i =
                            0;

                    while (LOMUtil.getString(LOMUtil.getLifeCycleVersion(lom), i) !=
                            null) {

                        String versionLOM =
                                LOMUtil.getString(LOMUtil.getLifeCycleVersion(lom),
                                i);
                        String languageLOM =
                                LOMUtil.getLanguage(LOMUtil.getLifeCycleVersion(lom),
                                i);

                        instance =
                                "#slsGV" +
                                inst.getLocalName() + "-" + String.valueOf(i);
                        Individual singleInstance =
                                ont.createIndividual(nsName + instance,
                                singleLangStringClass);

                        if (versionLOM != null) {
                            RDFNode versionValue =
                                    ont.createTypedLiteral(versionLOM);
                            singleInstance.setPropertyValue(hasValueProperty,
                                    versionValue);
                        } else {
                            String log =
                                    "The Version field of the lifeCycle category must contain a value";
                            errorWriter.println(log);
                        }
                        if (languageLOM != null) {
                            RDFNode languageValue =
                                    ont.createTypedLiteral(languageLOM);
                            singleInstance.setPropertyValue(inLanguageProperty,
                                    languageValue);
                        } else {
                            String log =
                                    "The Version field of the lifeCycle category must contain a value";
                            errorWriter.println(log);
                        }
                        langInstance.addProperty(includeLangStringProperty,
                                singleInstance);
                        i++;
                    }
                    ObjectProperty versionProperty =
                            ont.getObjectProperty(nsName + "#hasVersion");
                    inst.setPropertyValue(versionProperty, langInstance);
                }
            }

        } else if (category.equals("Technical")) {
            //4.5 installation remarks
            if (element.equals("InstallationRemarks")) {
                if (LOMUtil.getTechnicalInstallationRemarks(lom) != null) {
                    instance =
                            "#lsTI" +
                            inst.getLocalName();
                    Individual langInstance =
                            ont.createIndividual(nsName +
                            instance, langStringClass);
                    int i =
                            0;

                    while (LOMUtil.getString(LOMUtil.getTechnicalInstallationRemarks(lom),
                            i) != null) {
                        String installationLOM =
                                LOMUtil.getString(LOMUtil.getTechnicalInstallationRemarks(lom),
                                i);
                        String languageLOM =
                                LOMUtil.getLanguage(LOMUtil.getTechnicalInstallationRemarks(lom),
                                i);

                        instance =
                                "#slsTI" +
                                inst.getLocalName() + "-" + String.valueOf(i);
                        Individual singleInstance =
                                ont.createIndividual(nsName + instance,
                                singleLangStringClass);

                        if (installationLOM != null) {
                            RDFNode installationValue =
                                    ont.createTypedLiteral(installationLOM);
                            singleInstance.setPropertyValue(hasValueProperty,
                                    installationValue);
                        } else {
                            String log =
                                    "The Installation Remarks field of the Technical category must contain a value";
                            errorWriter.println(log);
                        }
                        if (languageLOM != null) {
                            RDFNode languageValue =
                                    ont.createTypedLiteral(languageLOM);
                            singleInstance.setPropertyValue(inLanguageProperty,
                                    languageValue);
                        }
                        langInstance.addProperty(includeLangStringProperty,
                                singleInstance);

                        i++;
                    }
                    ObjectProperty installationProperty =
                            ont.getObjectProperty(nsName +
                            "#hasInstallationRemark");
                    inst.setPropertyValue(installationProperty, langInstance);
                }

            } //4.6 other platform requirements
            else if (element.equals("OtherPlatformRequirements")) {

                if (LOMUtil.getTechnicalOtherPlatformRequirements(lom) != null) {
                    instance =
                            "#lsTOP" +
                            inst.getLocalName();
                    Individual langInstance =
                            ont.createIndividual(nsName +
                            instance, langStringClass);
                    int i =
                            0;
                    while (LOMUtil.getString(LOMUtil.getTechnicalOtherPlatformRequirements(lom),
                            i) != null) {
                        String otherplatformLOM =
                                LOMUtil.getString(LOMUtil.getTechnicalOtherPlatformRequirements(lom),
                                i);
                        String languageLOM =
                                LOMUtil.getLanguage(LOMUtil.getTechnicalOtherPlatformRequirements(lom),
                                i);

                        instance =
                                "#slsTOP" +
                                inst.getLocalName() + "-" + String.valueOf(i);
                        Individual singleInstance =
                                ont.createIndividual(nsName + instance,
                                singleLangStringClass);

                        if (otherplatformLOM != null) {
                            RDFNode otherplatformValue =
                                    ont.createTypedLiteral(otherplatformLOM);
                            singleInstance.setPropertyValue(hasValueProperty,
                                    otherplatformValue);
                        } else {
                            String log =
                                    "The OtherPlatformRequirements field of the Technical category must contain a value";
                            errorWriter.println(log);
                        }
                        if (languageLOM != null) {
                            RDFNode languageValue =
                                    ont.createTypedLiteral(languageLOM);
                            singleInstance.setPropertyValue(inLanguageProperty,
                                    languageValue);
                        } else {
                            String log =
                                    "The Language field of OtherPlatformRequirements in the Techincal category must contain a value";
                            errorWriter.println(log);
                        }
                        langInstance.addProperty(includeLangStringProperty,
                                singleInstance);

                        i++;
                    }
                    ObjectProperty otherplatformProperty =
                            ont.getObjectProperty(nsName +
                            "#hasOtherPlatformRequirement");
                    inst.setPropertyValue(otherplatformProperty, langInstance);
                }
            }
        } else if (category.equals("Rights")) {
            //6.3 description 
            if (element.equals("RightsDescription")) {
                if (LOMUtil.getRightsDescription(lom) != null) {
                    instance =
                            "#lsRD" +
                            inst.getLocalName();
                    Individual langInstance =
                            ont.createIndividual(nsName +
                            instance, langStringClass);
                    int i =
                            0;
                    while (LOMUtil.getString(LOMUtil.getRightsDescription(lom),
                            i) != null) {
                        String rightsdescriptionLOM =
                                LOMUtil.getString(LOMUtil.getRightsDescription(lom),
                                i);
                        String languageLOM =
                                LOMUtil.getLanguage(LOMUtil.getRightsDescription(lom),
                                i);

                        instance =
                                "#slsRD" +
                                inst.getLocalName() + "-" + String.valueOf(i);
                        Individual singleInstance =
                                ont.createIndividual(nsName + instance,
                                singleLangStringClass);

                        if (rightsdescriptionLOM != null) {
                            RDFNode rightsdescriptionValue =
                                    ont.createTypedLiteral(rightsdescriptionLOM);
                            singleInstance.setPropertyValue(hasValueProperty,
                                    rightsdescriptionValue);
                        } else {
                            String log =
                                    "The Description field of the Rights category must contain a value";
                            errorWriter.println(log);
                        }
                        if (languageLOM != null) {
                            RDFNode languageValue =
                                    ont.createTypedLiteral(languageLOM);
                            singleInstance.setPropertyValue(inLanguageProperty,
                                    languageValue);
                        } else {
                            String log =
                                    "The Language field of Description in the Rights category must contain a value";
                            errorWriter.println(log);
                        }
                        langInstance.addProperty(includeLangStringProperty,
                                singleInstance);
                        i++;
                    }
                    ObjectProperty descriptionProperty =
                            ont.getObjectProperty(nsName +
                            "#hasCommentsOnConditionsOfUse");
                    inst.setPropertyValue(descriptionProperty, langInstance);
                }
            }
        }

    }
}
    


